<template>
  <div :style="{height:props.chartHeight}" ref="chart" class="chart"></div>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, markRaw, watch } from 'vue';
import * as echarts from 'echarts/core';
import {
    TitleComponent,
    TooltipComponent,
    GridComponent,
    DatasetComponent,
    TransformComponent,
    LegendComponent
} from 'echarts/components';
import { PieChart } from 'echarts/charts';
import { LabelLayout, UniversalTransition } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';

echarts.use([
    TitleComponent,
    TooltipComponent,
    GridComponent,
    DatasetComponent,
    TransformComponent,
    LegendComponent,
    PieChart,
    CanvasRenderer,
    LabelLayout,
    UniversalTransition
])

const chart = ref<HTMLDivElement>()
const myChart = ref<any>()
const props = defineProps(['data', 'title', 'chartHeight'])

const getOption = () => {
    const total = props.data?.reduce((sum: number, item: any) => sum + (item.value || 0), 0) || 0
    
    return {
        color: ['#2B5AED', '#FA5247', '#1CCBB6', '#F625AF', '#FFB435'],
        title: {
            text: total,
            subtext: props.title,
            left: 'center',
            top: '34%',
            textStyle: {
                fontSize: 32,
                color: '#686B73',
                align: 'center',
            },
            subtextStyle: {
                fontSize: 14,
                color: '#686B73',
            },
        },
        tooltip: {
            trigger: 'item',
        },
        legend: {
            show: false,
            bottom: 0,
            icon: 'circle',
        },
        series: [
            {
                type: 'pie',
                radius: ['60%', '70%'],
                avoidLabelOverlap: true,
                label: {
                    show: false,
                },
                emphasis: {
                    label: {
                        show: true,
                        fontSize: '40',
                        fontWeight: 'bold',
                    }
                },
                labelLine: {
                    show: false,
                },
                data: props.data || [],
            }
        ]
    }
}

// 初始化图表
const initChart = () => {
    if (!chart.value) return
    
    // 如果已存在实例，先销毁
    if (myChart.value) {
        myChart.value.dispose()
    }
    
    myChart.value = markRaw(echarts.init(chart.value))
    const resizeHandler = () => myChart.value?.resize()
    
    window.addEventListener('resize', resizeHandler)
    myChart.value._resizeHandler = resizeHandler
    
    return myChart.value
}

// 更新图表
const updateChart = () => {
    if (!myChart.value) {
        myChart.value = initChart()
    }
    
    if (myChart.value) {
        myChart.value.setOption(getOption())
    }
}

onMounted(() => {
    updateChart()
})

watch(
    () => props.data,
    () => {
        updateChart()
    },
    { deep: true }
)

onBeforeUnmount(() => {
    if (myChart.value) {
        if (myChart.value._resizeHandler) {
            window.removeEventListener('resize', myChart.value._resizeHandler)
        }
        myChart.value.dispose()
        myChart.value = null
    }
})
</script>
<style scoped lang="less">
.chart {
    width: 100%;
}
</style>